package com.huawei.petSystemdemo.utils;


import android.os.AsyncTask;

import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MyRequest<ReturnType> {
    //private static String baseUrl = "http://122.9.112.122:8080/front";
    private static String baseUrl = "http://192.168.248.1:8080/front";
    private static String TAG = "network";

    public static void setTAG(String TAG) {
        MyRequest.TAG = TAG;
    }

    public static String getBaseUrl() {
        return baseUrl;
    }

    public static void setBaseUrl(String baseUrl) {
        MyRequest.baseUrl = baseUrl == null ? "" : baseUrl;
    }

    public static String getTAG() {
        return TAG;
    }

    /**
     *
     * @param u 相对url
     * @param params 请求参数
     * @param callback 回调
     */
    public static void get(String u, Map<String, Object> params, Callback callback) {
        String realurl = realUrl(u, params);

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(realurl)
                .get()
                .build();
        Call call = client.newCall(request);
        call.enqueue(callback);
    }

    /**
     *
     * @param u 相对url
     * @param callback 回调
     */
    public static void get(String u, Callback callback) {
        get(u, null, callback);
    }

    /**
     *
     * @param u 相对url
     * @param requestBody 请求体
     * @param callback 回调
     */
    public static void post(String u, RequestBody requestBody, Callback callback) {
        String realurl = realUrl(u, null);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(realurl)
                .post(requestBody)
                .build();

        Call call = client.newCall(request);
        call.enqueue(callback);
    }

    public static void post(String u, Callback callback) {
        post(u, (RequestBody) null, callback);
    }

    public static void post(String u, Map<String, Object> params, Callback callback) {
        RequestBody requestBody = convertMapToRequestBody(params);
        post(u, requestBody, callback);
    }

    public static void get(String u, Map<String, Object> params, Consumer<String> callback) {
        String realurl = realUrl(u, params);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(realurl)
                .get()
                .build();
        Call call = client.newCall(request);
        new JsonHttpAsyncTsak(call, callback).execute();
    }

    public void getStream(String u, Map<String, Object> params, Function<Response, ReturnType> doInBackground, Consumer<ReturnType> onPostExecute) {
        String real = realUrl(u, params);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(real)
                .get()
                .build();
        Call call = client.newCall(request);
        new StreamHttpAsyncTsak<ReturnType>(call, doInBackground, onPostExecute).execute();
    }

    public void postStream(String u, RequestBody requestBody, Function<Response, ReturnType> doInBackground, Consumer<ReturnType> onPostExecute) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(u)
                .post(requestBody)
                .build();
        Call call = client.newCall(request);
        new StreamHttpAsyncTsak<ReturnType>(call, doInBackground, onPostExecute).execute();
    }

    public static void post(String u, RequestBody requestBody, Consumer<String> callback) {
        String realurl = realUrl(u, null);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(realurl)
                .post(requestBody)
                .build();

        Call call = client.newCall(request);
        new JsonHttpAsyncTsak(call, callback).execute();
    }

    public static void post(String u, Map<String, Object> params, Consumer<String> callback) {
        RequestBody requestBody = convertMapToRequestBody(params);
        post(u, requestBody, callback);
    }

    private static RequestBody convertMapToRequestBody(Map<String, Object> params) {
        FormBody.Builder builder = null;
        if (params != null)
        {
            builder = new FormBody.Builder();
            for (String key : params.keySet()) {
                Object value = params.get(key);
                if (value != null)
                    builder.add(key, value.toString());
            }
        }

        return builder.build();
    }

    private static String realUrl(String url, Map<String, Object> params) {
        if (url == null || url.length() == 0)
            throw new RuntimeException("url为空");

        if (url.charAt(0) != '/')
            url = url + '/';

        String real = baseUrl + url;

        if (params != null && params.size() > 0)
        {
            String path = "";
            for (String key : params.keySet()) {
                String param = "&" + key + "=" + params.get(key);
                path += param;
            }

            path = path.substring(1);
            real = real+ "?" + path;
        }

        return real;
    }
}

class JsonHttpAsyncTsak extends AsyncTask<Void, Void, String> {
    Call call;
    Consumer<String> callback;

    public JsonHttpAsyncTsak(Call call, Consumer<String> callback) {
        this.call = call;
        this.callback = callback;
    }

    @Override
    protected String doInBackground(Void... voids) {
        String json = null;
        try {
            Response response = call.execute();
            if (response.isSuccessful())
                json = response.body().string();
            else
                json = JSON.toJSONString(new HttpResult(HttpResultType.FAIL.getCode(), "请求失败"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return json;
    }

    @Override
    protected void onPostExecute(String json) {
        callback.accept(json);
    }
}


class StreamHttpAsyncTsak<ReturnType> extends AsyncTask<Void, Void, ReturnType> {
    Call call;
    Function<Response, ReturnType> doInBackground;
    Consumer<ReturnType> onPostExecute;

    public StreamHttpAsyncTsak(Call call, Function<Response, ReturnType> doInBackground, Consumer<ReturnType> onPostExecute) {
        this.call = call;
        this.doInBackground = doInBackground;
        this.onPostExecute = onPostExecute;
    }

    @Override
    protected ReturnType doInBackground(Void... voids) {
        Response response = null;
        try {
            response = call.execute();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return doInBackground.apply(response);
    }

    @Override
    protected void onPostExecute(ReturnType ret) {
        onPostExecute.accept(ret);
    }
}